"""
模型工厂类
根据配置创建相应的模型适配器
支持未来模型的自动兼容
"""

from typing import Optional
import logging
from .base_adapter import BaseModelAdapter
from .openai_adapter import OpenAIAdapter
from .gemini_adapter import GeminiAdapter
from .doubao_adapter import DoubaoAdapter
from .claude_adapter import ClaudeAdapter
from .zhipu_adapter import ZhipuAdapter
from .local_adapter import LocalModelAdapter

logger = logging.getLogger(__name__)


class ModelFactory:
    """模型适配器工厂类"""

    @staticmethod
    def create_adapter(
        provider: str,
        api_key: str,
        api_url: Optional[str] = None,
        model: Optional[str] = None
    ) -> BaseModelAdapter:
        """
        创建模型适配器

        Args:
            provider: 提供商名称 (支持预定义提供商和自定义提供商)
            api_key: API密钥
            api_url: API地址 (某些提供商需要)
            model: 模型名称 (支持任意模型名称)

        Returns:
            对应的模型适配器实例
        """
        provider = provider.lower().strip()

        # 预定义的提供商配置
        if provider == "openai":
            if not api_url:
                api_url = "https://api.openai.com/v1/chat/completions"
            if not model:
                model = "gpt-3.5-turbo"
            return OpenAIAdapter(api_key, api_url, model)

        elif provider == "deepseek":
            if not api_url:
                api_url = "https://api.deepseek.com/v1/chat/completions"
            if not model:
                model = "deepseek-chat"
            return OpenAIAdapter(api_key, api_url, model)

        elif provider == "gemini":
            if not model:
                model = "gemini-pro"
            return GeminiAdapter(api_key, model)

        elif provider == "doubao":
            if not api_url:
                api_url = "https://ark.cn-beijing.volces.com/api/v3/chat/completions"
            if not model:
                model = "doubao-pro-4k"
            return DoubaoAdapter(api_key, api_url, model)

        elif provider == "claude":
            if not model:
                model = "claude-3-sonnet-20240229"
            return ClaudeAdapter(api_key, model)

        elif provider == "zhipu":
            if not api_url:
                api_url = "https://open.bigmodel.cn/api/paas/v4/chat/completions"
            if not model:
                model = "glm-4"
            return ZhipuAdapter(api_key, api_url, model)

        elif provider == "local":
            if not api_url:
                api_url = "http://localhost:11434/v1/chat/completions"  # Ollama默认地址
            if not model:
                model = "llama2"
            if not api_key:
                api_key = "local"  # 本地模型可能不需要API密钥
            return LocalModelAdapter(api_key, api_url, model)

        else:
            # 尝试自动检测提供商类型
            try:
                from app.config.future_models_config import future_models
                detected_provider = future_models.auto_detect_provider(
                    api_url or "", model or "")

                if detected_provider != "custom" and detected_provider != provider:
                    logger.info(f"自动检测到提供商类型: {detected_provider}，重新创建适配器")
                    return ModelFactory.create_adapter(detected_provider, api_key, api_url, model)

                # 检查是否为新兴提供商
                provider_config = future_models.get_provider_config(provider)
                if provider_config:
                    logger.info(f"使用新兴提供商配置: {provider_config['name']}")
                    if not api_url:
                        api_url = provider_config.get("default_url")
                    if not model:
                        model = provider_config.get("default_model")

            except ImportError:
                logger.warning("未来模型配置模块不可用，使用默认处理")

            # 对于未知的提供商，尝试使用通用OpenAI兼容适配器
            logger.warning(f"未知的提供商 '{provider}'，尝试使用通用OpenAI兼容适配器")

            # 如果没有提供API URL，抛出错误
            if not api_url:
                raise ValueError(f"自定义提供商 '{provider}' 需要提供 API URL")

            # 如果没有提供模型名称，使用提供商名称作为默认模型
            if not model:
                model = provider
                logger.info(f"未指定模型名称，使用提供商名称作为模型: {model}")

            # 创建通用适配器
            from .generic_adapter import GenericAdapter
            return GenericAdapter(api_key, api_url, model, provider)

    @staticmethod
    def get_supported_providers() -> list:
        """获取支持的提供商列表"""
        base_providers = ["openai", "deepseek", "gemini",
                          "doubao", "claude", "zhipu", "local", "custom"]

        # 添加新兴提供商
        try:
            from app.config.future_models_config import future_models
            emerging_providers = list(
                future_models.get_emerging_providers().keys())
            return base_providers + emerging_providers
        except ImportError:
            return base_providers

    @staticmethod
    def is_custom_provider(provider: str) -> bool:
        """检查是否为自定义提供商"""
        known_providers = ["openai", "deepseek", "gemini",
                           "doubao", "claude", "zhipu", "local"]
        return provider.lower().strip() not in known_providers

    @staticmethod
    def get_provider_info() -> dict:
        """获取提供商信息"""
        return {
            "openai": {
                "name": "OpenAI",
                "description": "OpenAI GPT系列模型",
                "default_model": "gpt-3.5-turbo",
                "requires_url": True,
                "default_url": "https://api.openai.com/v1/chat/completions"
            },
            "deepseek": {
                "name": "DeepSeek",
                "description": "DeepSeek AI模型",
                "default_model": "deepseek-chat",
                "requires_url": True,
                "default_url": "https://api.deepseek.com/v1/chat/completions"
            },
            "gemini": {
                "name": "Google Gemini",
                "description": "Google Gemini系列模型",
                "default_model": "gemini-pro",
                "requires_url": False,
                "default_url": None
            },
            "doubao": {
                "name": "字节跳动豆包",
                "description": "字节跳动豆包大模型",
                "default_model": "doubao-pro-4k",
                "requires_url": True,
                "default_url": "https://ark.cn-beijing.volces.com/api/v3/chat/completions"
            },
            "claude": {
                "name": "Anthropic Claude",
                "description": "Anthropic Claude系列模型",
                "default_model": "claude-3-sonnet-20240229",
                "requires_url": False,
                "default_url": None
            },
            "zhipu": {
                "name": "智谱AI",
                "description": "智谱AI GLM系列模型",
                "default_model": "glm-4",
                "requires_url": True,
                "default_url": "https://open.bigmodel.cn/api/paas/v4/chat/completions"
            },
            "local": {
                "name": "本地大模型",
                "description": "本地部署的大模型 (Ollama、LM Studio、vLLM等)",
                "default_model": "llama2",
                "requires_url": True,
                "default_url": "http://localhost:11434/v1/chat/completions"
            },
            "custom": {
                "name": "自定义提供商",
                "description": "支持任意OpenAI兼容的API接口，包括最新发布的模型",
                "default_model": "custom-model",
                "requires_url": True,
                "default_url": "https://api.example.com/v1/chat/completions",
                "note": "使用自定义提供商时，请确保API接口兼容OpenAI格式"
            }
        }

    @staticmethod
    def validate_custom_config(provider: str, api_key: str, api_url: str, model: str) -> tuple[bool, str]:
        """
        验证自定义提供商配置

        Returns:
            (is_valid, error_message)
        """
        if not provider or provider.strip() == "":
            return False, "提供商名称不能为空"

        if not api_key or api_key.strip() == "":
            return False, "API密钥不能为空"

        if not api_url or api_url.strip() == "":
            return False, "API地址不能为空"

        if not model or model.strip() == "":
            return False, "模型名称不能为空"

        # 检查URL格式
        if not (api_url.startswith("http://") or api_url.startswith("https://")):
            return False, "API地址必须以http://或https://开头"

        # 检查是否为占位符
        placeholder_keys = [
            "your-api-key-here",
            "your-custom-api-key-here",
            "sk-xxxxxxxxxxxxxxxx"
        ]
        if api_key in placeholder_keys:
            return False, "请配置真实的API密钥，不要使用占位符"

        return True, ""
